#include "stdafx.h"
#include "xfImgBit16.h"

#define DKQ_MIN(a,b) ( ( (a)<(b) ) ? (a):(b) ) 
#define DKQ_MAX(a,b) ( ( (a)>(b) ) ? (a):(b) ) 

int xfImgBit16::Filter(zkFilter *pInput,long* kernel, long Ksize, long Kfactor, long Koffset)
{
	int nNewKoffset = 0;
	if( Koffset > 0 )
	{
		nNewKoffset = (Koffset+1) * ( m_nGrayLevels >> 8 ) - 1;
	}

	long k2   = Ksize/2;
	long kmax = Ksize-k2;
	long b,i;

	long xmin,xmax,ymin,ymax;
	long xmin2,xmax2,ymin2,ymax2;
	xmin = ymin = 0;
	xmax = pInput->nWidth;
	ymax = pInput->nHeight;
	xmin2 = xmin + k2;
	xmax2 = xmax - kmax;
	ymin2 = ymin + k2;
	ymax2 = ymax - kmax;

	int nWidth   = pInput->nWidth;
	int nHeight  = pInput->nHeight;
	int nMaxGray = (1 << pInput->nBpp)-1;

	WORD* cPtr  = (WORD*)pInput->pwSrc;
	WORD* cPtr2 = (WORD*)pInput->pwDst;
	if( NULL == cPtr2 )
	{
		return -1;
	}

	int iCount;
	int iY, iY2, iY1;
	if( Kfactor==0 ) 
	{
		Kfactor = 1;
	}

	long x,y,k,j;

	for(y=ymin;y<k2;y++)
	{
		iY = y*nWidth;
		memcpy(cPtr2+iY,cPtr+iY,nWidth*sizeof(WORD));
	}
	for(y=ymax-kmax;y<ymax;y++)
	{
		iY = y*nWidth;
		memcpy(cPtr2+iY,cPtr+iY,nWidth*sizeof(WORD));
	}
	for(y=ymin; y<ymax; y++)
	{
		for(x=xmin; x<k2; x++)
		{
			iY = y*nWidth+x;
			cPtr2[iY] = cPtr[iY];
		}
		for(x=xmax-kmax; x<xmax; x++)
		{
			iY = y*nWidth+x;
			cPtr2[iY] = cPtr[iY];
		}
	}

	for(y=ymin2; y<ymax2; y++)
	{
		for(x=xmin2; x<xmax2; x++)
		{
			iY = y*nWidth+x;
			{
				b=0;
				iCount = 0;
				iY2 = ((y-k2)*xmax);
				for(j=-k2;j<kmax;j++)
				{
					iY1 = iY2+x;
					for(k=-k2;k<kmax;k++)
					{
						i=kernel[iCount];
						b += cPtr[iY1+k] * i;
						iCount++;
					}
					iY2 += xmax;
				}
				cPtr2[iY] = DKQ_MIN(m_nMaxGray, DKQ_MAX(0,(int)(b/Kfactor + nNewKoffset)));
			}
		}
	}

	return 0;
}